package cn.wolfcode.service.impl;

import cn.wolfcode.common.web.Result;
import cn.wolfcode.domain.Product;
import cn.wolfcode.domain.SeckillProduct;
import cn.wolfcode.domain.SeckillProductVo;
import cn.wolfcode.feign.ProductFeignApi;
import cn.wolfcode.mapper.SeckillProductMapper;
import cn.wolfcode.redis.SeckillRedisKey;
import cn.wolfcode.service.ISeckillProductService;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class SeckillProductServiceImpl implements ISeckillProductService {
    @Autowired
    private SeckillProductMapper seckillProductMapper;  // 注入Mapper查询数据库
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private ProductFeignApi productFeignApi;    // 注入Feign

    @Override
    public List<SeckillProductVo> selectByTime(int time) {
        // 首先查询秒杀商品数据
        List<SeckillProduct> seckillProducts = seckillProductMapper.queryCurrentlySeckillProduct(time);
        // 将商品id放到list集合中
        ArrayList<Long> ids = new ArrayList<>();
        for (SeckillProduct seckillProduct : seckillProducts) {
            ids.add(seckillProduct.getProductId());
        }
        // 远程调用商品服务查询商品数据 Result<List<Product>>
        Result<List<Product>> result = productFeignApi.queryByIds(ids);
        /**
         * result=null
         * result=500**
         * result=200 {code:200,msg:"操作成功",data:List<Product>}
         */

        List<SeckillProductVo> vos = new ArrayList<>();
        if (result != null && !result.hasError()) {
            List<Product> productList = result.getData();
            Map<Long, Product> map = new HashMap<>();
            for (Product product : productList) {
                map.put(product.getId(), product);
            }

            for (SeckillProduct seckillProduct : seckillProducts) {
                SeckillProductVo seckillProductVo = new SeckillProductVo();
                Product product = map.get(seckillProduct.getProductId());
                BeanUtils.copyProperties(product, seckillProductVo);
                BeanUtils.copyProperties(seckillProduct, seckillProductVo);
                vos.add(seckillProductVo);
            }
        }
        // 进行聚合操作 最终返回一个List<SeckillProductVO>
        return vos;
    }

    @Override
    public List<SeckillProductVo> queryByTime(Integer time) {
        // 在redis中查询,values()方法获取hash中所有的value
        List<Object> list = redisTemplate.opsForHash().values(SeckillRedisKey.SECKILL_PRODUCT_LIST.getRealKey(time + ""));
        List<SeckillProductVo> vos = new ArrayList<>();
        for (Object objJson : list) {
            // 存到时候是存的JSON字符串需要转成vo格式
            vos.add(JSON.parseObject(objJson+"",SeckillProductVo.class));
        }
        return vos;
    }

    @Override
    public SeckillProductVo  find(Integer time, Long seckillId) {
        Object objJson = redisTemplate.opsForHash().get(SeckillRedisKey.SECKILL_PRODUCT_LIST.getRealKey(time + ""), seckillId + "");
        // 判断是否为空
        if (StringUtils.isEmpty(objJson + "")) {
            return null;
        }
        return JSON.parseObject(objJson + "", SeckillProductVo.class);
    }

    @Override
    public void replenishRedisStockCount(Integer time, Long seckillId) {
        // 1.查询mysql中真实库存
        int stockCount = seckillProductMapper.getStockCount(seckillId);
        // 2.把库存重新放回redis中
        redisTemplate.opsForHash().put(SeckillRedisKey.SECKILL_STOCK_COUNT_HASH.getRealKey(time.toString()),seckillId.toString(),stockCount+"");
    }
}
